package aufgabe3;

import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class MengerSchwamm extends JFrame {

	private Canvas3D myCanvas3D;

	private static final long serialVersionUID = 3307904838600679666L;

	public MengerSchwamm() {
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
		SimpleUniverse simpUniv = new SimpleUniverse(myCanvas3D);
		simpUniv.getViewingPlatform().setNominalViewingTransform();
		createSceneGraph(simpUniv);
		addLight(simpUniv);
		
		OrbitBehavior ob = new OrbitBehavior(myCanvas3D);
		ob.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE));
		simpUniv.getViewingPlatform().setViewPlatformBehavior(ob);
		
		setTitle("Menger-Schwamm");
		setSize(729, 729);
		getContentPane().add("Center", myCanvas3D);
		setVisible(true);
	}

	private void createSceneGraph(SimpleUniverse su) {
		Appearance app = new Appearance();
		setToMyDefaultAppearance(app, new Color3f(0.0f, 0.0f, 0.0f));
		BranchGroup theScene = new BranchGroup();
		
		float size = 0.2f;
		
		for (int i = 0; i < 27; i++) {
			if(i % 9 == 4 || ((i / 9) == 1 & (i % 2 == 0)))
				continue;
			
			TransformGroup box = createSponge(su, size);

			Transform3D tfBox = new Transform3D();
			tfBox.setTranslation(new Vector3f(((i % 3) * (size * 2)) - (size * 2), ((int)((i % 9) / 3) * (size * 2)) - (size * 2), ((i / 9) * (size * 2)) - (size * 2)));
			
			TransformGroup tgBox = new TransformGroup(tfBox);
			tgBox.addChild(box);
			
			theScene.addChild(tgBox);
		}

	    Background bg = new Background(new Color3f(1.0f,1.0f,1.0f));
	    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE);
	    bg.setApplicationBounds(bounds);
	    theScene.addChild(bg);

	    theScene.compile();

	    su.addBranchGraph(theScene);
	}
	
	public TransformGroup createSponge(SimpleUniverse su, float size) {
		Appearance app = new Appearance();
		setToMyDefaultAppearance(app, new Color3f(0.0f, 0.0f, 0.0f));
		TransformGroup tgAll = new TransformGroup();

		size /= 3;
		for (int i = 0; i < 27; i++) {
			
			if(i % 9 == 4 || ((i / 9) == 1 & (i % 2 == 0)))
				continue;
			
			Box box = new Box(size, size, size, app);

			Transform3D tfBox = new Transform3D();	
			tfBox.setTranslation(new Vector3f(((i % 3) * (size * 2)) - (size * 2), ((int)((i % 9) / 3) * (size * 2)) - (size * 2), ((i / 9) * (size * 2)) - (size * 2)));
			
//			System.out.println(i);
//			System.out.println("x: " + (((i % 3) * (size * 2)) - (size * 2)));
//			System.out.println("y: " + (((int)((i % 9) / 3) * (size * 2)) - (size * 2)));
//			System.out.println("z: " + (((i / 9) * (size * 2)) - (size*2)));	
			
			TransformGroup tgBox = new TransformGroup(tfBox);
			tgBox.addChild(box);
			
			tgAll.addChild(tgBox);
		}
		
		return tgAll;
	}
	
	
	private void addLight(SimpleUniverse su) {
		BranchGroup bgLight = new BranchGroup();
		
		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
		Color3f lightColour1 = new Color3f(1.0f, 1.0f, 1.0f);
		Vector3f lightDir1 = new Vector3f(-1.0f, 0.0f, -0.5f);
		DirectionalLight light1 = new DirectionalLight(lightColour1, lightDir1);
		light1.setInfluencingBounds(bounds);
		
		bgLight.addChild(light1);
		su.addBranchGraph(bgLight);
	}
	
	private static void setToMyDefaultAppearance(Appearance app, Color3f col) {
		app.setMaterial(new Material(col, col, col, col, 150.0f));
	}
	
	public static void main(String[] args) {
		new MengerSchwamm();
	}
}
